/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Copyright 2002-2003 by Mark Wolgemuth, All rights reserved.             */
/* Copyright 2002-2003 by Employease, Inc.  All rights reserved.           */
/*                                                                         */
/* Redistribution and use in source and binary forms, with or without      */
/* modification, are permitted provided that the following conditions      */
/* are met:                                                                */
/*                                                                         */
/*    1. Redistributions of source code must retain the above copyright    */
/* notice, this list of conditions and the following disclaimer.           */
/*    2. Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the     */
/* documentation and/or other materials provided with the distribution.    */
/*                                                                         */
/* THIS SOFTWARE IS PROVIDED BY THE MOD_ATHENA PROJECT ``AS IS'' AND ANY   */
/* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE       */
/* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR      */
/* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR        */
/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,   */
/* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,     */
/* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR      */
/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY     */
/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT            */
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   */
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*                                                                         */
/* This code is inspired by natd.c by Ari Suutari working for the FreeBSD  */
/* team. Thanks man!                                                       */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


#include "athd.h"

/* bsd includes */
#ifdef ATHD_IP_LB /* hide all from nonbsd */
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#ifdef HAVE_MACHINE_IN_CKSUM_H
#include <machine/in_cksum.h> /* not in darwin */
#endif /* HAVE_MACHINE_IN_CKSUM_H */
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/route.h>
#include <arpa/inet.h>

#ifdef HAVE_ALIAS_H
#include <alias.h>
#endif /* HAVE_ALIAS_H */

/* privates */
static apr_pool_t *_athd_lb_pool = NULL; 
static ath_list *_farm_alias_addrs = NULL;
static int _lb_port;

static int _athd_lb_thread_hup_handler(int sig);

#endif /* ATHD_IP_LB */

static void * _athd_lb_thread_cleanup(void *ctx);

static int _dienow;
static int _no_lb;
/* end privates */



void *
athd_lb_thread(void *ctx)
{
    athd_conf *conf = ctx;
    int laststate, lasttype;
    struct sigaction action = { NULL } ;

    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &laststate);
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &lasttype);
    pthread_cleanup_push((void *)_athd_lb_thread_cleanup, (void *)conf);

    action.sa_handler = athd_connection_reset;
    sigaction(SIGPIPE, &action, 0);

#ifdef ATHD_IP_LB
    athd_log(ATHD_INFO, "LB Thread: Enter");
    for (; (!_dienow) ;)
      {
	  if (_no_lb)
	      apr_sleep(ATHD_WETDREAM);
	  else
	    {
		pthread_testcancel();
		/* remove this once select is handled */
		apr_sleep(XTH_SEC(1000));
	    }
      }
#endif /* ATHD_IP_LB */
    pthread_cleanup_pop(1);
}

apr_status_t
athd_lb_thread_setup(apr_pool_t *pglobal)
{
    int rv = APR_SUCCESS;
    ath_node *listctx;
    athd_conf *conf = athd_conf_current_get();
    _dienow = 0;
#ifdef ATHD_IP_LB
    ASSERT(conf);
    /* find farms we need to look for and lb */
    if (!conf->ip_lb)
	_no_lb = 1;
    else
      {
	  _no_lb = 0;
	  ath_list_rewind_r(conf->ip_farms, &listctx);
	  while (ath_list_hasnext_r(conf->ip_farms, &listctx))
	    {
		
	    }
	  /* initialize alias internals */
	  PacketAliasInit();
      }
#else
    _no_lb = 1;
#endif /* ATHD_ IP_LB */
    return rv;
}

void
athd_lb_thread_die()
{
    _dienow = 1;
}

static void *
_athd_lb_thread_cleanup(void *ctx)
{
    athd_log(ATHD_INFO, "LB Thread: Exit");
}

#ifdef ATHD_IP_LB /* private func hide */

static int
_athd_lb_thread_hup_handler(int sig)
{

}

#endif /* ATHD_IP_LB */
